import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;

public class Data {
	public ArrayList<double[]> dataset = new ArrayList<double []>();
	public int attributeNum;
	public double[] max;
	public double[] min;
	
	private int[] sa_ran_array;
	public Data(String path){
		try{
			BufferedReader f = new BufferedReader(new FileReader(path));
	        // input file name goes above
					
			String line = f.readLine();
			StringTokenizer st;
			while (line != null){
				st = new StringTokenizer(line);	
				int n = st.countTokens();
				attributeNum = n;
				double[] tuple = new double[n];
				for (int i = 0; i < n; i++){
					tuple[i] = Double.parseDouble(st.nextToken());
				}
				dataset.add(tuple);
				line = f.readLine();
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	
	public void normalize(){
		int n = dataset.get(0).length;
		max = new double[n-2];
		min = new double[n-2];
		for (int i = 2; i < n; i++){
			max[i-2] = dataset.get(0)[i];
			min[i-2] = dataset.get(0)[i];
		}
		
		for (int i = 1; i < dataset.size(); i++){
			for (int j = 2; j < n; j++){
				if (dataset.get(i)[j] > max[j-2])
					max[j-2] = dataset.get(i)[j];
				if (dataset.get(i)[j] < min[j-2])
					min[j-2] = dataset.get(i)[j];							
			}
		}
		
		for (int i = 0; i < dataset.size(); i++){
			double[] tuple = dataset.get(i);
			for (int j = 2; j < n; j++){
				tuple[j] = (tuple[j] - min[j-2])/(max[j-2] - min[j-2]);
			}
			dataset.set(i, tuple);
		}
	}
	
	public void normalize(double[] min, double[] max){
		int n = dataset.get(0).length;
		
		for (int i = 0; i < dataset.size(); i++){
			double[] tuple = dataset.get(i);
			for (int j = 2; j < n; j++){
				tuple[j] = (tuple[j] - min[j-2])/(max[j-2] - min[j-2]);
			}
			dataset.set(i, tuple);
		}
	}
	
	public double calMisRecord(Network network){
		int yes = 0;
		int no = 0;
		for (int i = 0; i < dataset.size(); i++){
			if (network.testTuple(dataset.get(i))){
				yes++;
			} else {
				no++;
			}
		}
		return (double)yes / (yes+no);
	}
	
	public void genSaRandomArray(){
	    Random seed=new Random();
	    Map<Integer, Integer> hm=new HashMap<Integer, Integer>();
	    int sa_size=(dataset.size()>10000)?(dataset.size()/10):dataset.size();
	    this.sa_ran_array=new int[sa_size];
	    for(int i=0;i<sa_ran_array.length;i++){
	        int index=0;
//          int index= Math.abs(seed.nextInt()) % dataset.size();
          while(hm.containsKey(index)){
              index= Math.abs(seed.nextInt()) % dataset.size();
          }
          hm.put(index, 1);
          this.sa_ran_array[i]=index;
	    }
	}
	
	public int calSaError(Network network){
	    double res=0.0;
	    for (int i = 0; i < sa_ran_array.length; i++){
	        res += network.getErrSquare(dataset.get(sa_ran_array[i]));
        }
	    res = res/2;
	    return (int)res;
	}
}
